# -*- coding: utf-8 -*-

#    OriginDB
#    Copyright (C) 2010  Jason Power <power.jg@gmail.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import sys
sys.path.append('../')

from PyQt4.QtGui import *
from PyQt4 import QtCore

import openbabel

from compound import Compound
from atom import Atom
from bond import Bond
from bondHelper import BondHelper

from tools import *

class EditorScene(QGraphicsScene):

	def __init__(self, mol, parent=None):
		QGraphicsScene.__init__(self, parent)

		if mol:
			self.compound = Compound(mol.OBMol)
		else:
			self.compound = Compound()

		self.addItem(self.compound)
		
		self.oldSelection = []

		#self.undoStack = QUndoStack()

		self.tool = None
		self.bond = ""
		self.item = openbabel.OBAtom()

		self.drawingBond = False
		self.beginDrawingBondAtom = None
		self.bondEnd = None
		self.bondEndSet = False

		self.connect(self, QtCore.SIGNAL("selectionChanged()"), self.newSelection)

	def getMol(self):
		return self.compound.mol

	def setTool(self, tool):
		self.tool = tool

	def setBond(self, bond):
		self.bond = bond

	def setItem(self, item):
		self.item = item

	def mousePressEvent(self, mouseEvent):
		if self.tool:
			self.tool(mouseEvent)
		if not mouseEvent.isAccepted():
			QGraphicsScene.mousePressEvent(self, mouseEvent)

	def mouseMoveEvent(self, mouseEvent):
		if self.drawingBond:
			self.bondEnd = self.bondHelper.changeEnd(mouseEvent.scenePos())
			self.bondEndSet = True
		else:
			QGraphicsScene.mouseMoveEvent(self, mouseEvent)

	def mouseReleaseEvent(self, mouseEvent):
		if not self.drawingBond:
			QGraphicsScene.mouseReleaseEvent(self, mouseEvent)
			return
		
		self.drawingBond = False
		self.removeItem(self.bondHelper)
		endAtom = None
		
		if self.bondEndSet:
			endPos = self.bondEnd
		else:
			endPos = mouseEvent.scenePos()
		self.bondEndSet = False
		for item in self.items(endPos):
			if type(item) == Atom:
				endAtom = item
				break
		if endAtom and endAtom.atom.GetIdx() == self.beginDrawingBondAtom.atom.GetIdx():
			if type(self.item) == openbabel.OBAtom:
				endAtom.setAtomicNum(self.item.GetAtomicNum())
				#command = ChangeAtomicNum(endAtom, self.item.GetAtomicNum())
				#self.undoStack.push(command)
			return
		
		if endAtom:
			endAtom = endAtom.atom
		
		if not endAtom:
			if type(self.item) == openbabel.OBAtom:
				endAtom = self.item
			else:
				endAtom = openbabel.OBAtom()
				endAtom.SetAtomicNum(6)
			self.compound.addAtom(endAtom, self.bondEnd)
			#command = AddAtom(endAtom, self, self.bondEnd)
			#self.undoStack.push(command)
		
		endAtom = None
		for item in self.items(self.bondEnd):
			if type(item) == Atom:
				endAtom = item.atom
				break

		self.compound.addBond(self.beginDrawingBondAtom.atom, endAtom, self.bond)
		#command = AddBond(self.beginDrawingBondAtom.atom, endAtom, self.bond, self)
		#self.undoStack.push(command)
		self.beginDrawingBondAtom.updateSymbol()
		self.beginDrawingBondAtom = None

	def newSelection(self):
		for item in self.oldSelection:
			item.setSelected(False)
		self.oldSelection = self.selectedItems()
		for item in self.oldSelection:
			item.setSelected(True)


	def draw(self, mouseEvent):
		pos = mouseEvent.scenePos()

		items = self.items(mouseEvent.scenePos())
		atom = None
		for item in items:
			if type(item) == Atom:
				self.beginDrawingBondAtom = item
				self.drawingBond = True
				self.bondHelper = BondHelper(item.pos(), self.bond)
				self.addItem(self.bondHelper)
				return
			if type(item) == Bond:
				item.setType(self.bond)
				#command = ChangeBondType(item, self.bond)
				#self.undoStack.push(command)
				return

		if type(self.item) == openbabel.OBAtom:
			self.compound.addAtom(self.item, pos)
			#command = AddAtom(self.item, self, pos)
			#self.undoStack.push(command)

		elif type(self.item) == openbabel.OBMol:
			self.compound.addMolecule(self.item)
			#command = AddMolecule(self.item, self, pos)
			#self.undoStack.push(command)

	def move(self, mouseEvent):
		mouseEvent.ignore()

	def rotate(self, mouseEvent):
		pass

	def erase(self, mouseEvent):
		items = self.items(mouseEvent.scenePos())
		if not items:
			return

		toDel = None
		command = None
		for item in items:
			if type(item) == Atom:
				#toDel = item
				#command = RemoveAtom(item.atom, self)
				self.compound.removeAtom(item.atom)
				#break
				return
			elif type(item) == Bond:
				#command = RemoveBond(item.bond, self)
				#toDel = item
				self.compound.removeBond(item.bond)
				return
		
		if not toDel:
			return

		print "Found", type(toDel)

		#self.undoStack.push(command)

		mouseEvent.accept()